/*
 * Change Logs:
 * Date           Author       Notes
 * 2022-03-27     chenbin
 */
#include "fupdate.h"
#if (FBOOT_USING_FUPDATE == 1)

#define DBG_ENABLE
#define DBG_SECTION_NAME "fupdate"
#define DBG_LEVEL DBG_INFO
#include <rtdbg.h>

#include "fal.h"


#if (FUPDATE_USING_AES256 == 1)
/**
 * AES256 encryption algorithm option
 */
static uint8_t STR_FUPDATE_AES_IV[16 + 2];	// 16byte
static uint8_t STR_FUPDATE_AES_KEY[32 + 2]; // 32byte

RT_WEAK int fupdate_aes256_update(const char *aes_iv, const char *aes_key)
{
	int maxlen = 0;
	maxlen = rt_strlen((char *)aes_iv);
	if (maxlen > 16)
	{
		maxlen = 16;
	}
	rt_memset(STR_FUPDATE_AES_IV, 0, sizeof(STR_FUPDATE_AES_IV));
	rt_memcpy(STR_FUPDATE_AES_IV, aes_iv, maxlen);
	STR_FUPDATE_AES_IV[16] = '\0';

	maxlen = rt_strlen((char *)aes_key);
	if (maxlen > 32)
	{
		maxlen = 32;
	}
	rt_memset(STR_FUPDATE_AES_KEY, 0, sizeof(STR_FUPDATE_AES_KEY));
	rt_memcpy(STR_FUPDATE_AES_KEY, aes_key, maxlen);
	STR_FUPDATE_AES_KEY[32] = '\0';

	return 0;
}

RT_WEAK uint8_t *fupdate_aes256_iv_get(void)
{
	return STR_FUPDATE_AES_IV;
}
RT_WEAK uint8_t *fupdate_aes256_key_get(void)
{
	return STR_FUPDATE_AES_KEY;
}
#endif /* FUPDATE_USING_AES256 */


int fupdate_falprobe(const char* fal_part_name)
{
	return fupdate_rblprobe(fal_part_name, FUPDATE_MODE_SRC_FAL);
}

int fupdate_falcheck(const char* fal_part_name)
{
	return fupdate_rblcheck(fal_part_name, FUPDATE_MODE_SRC_FAL);
}

int fupdate_fal2fal(const char* fal_part_name, const char* fal_part_name_dest, uint32_t flags )
{
	return fupdate_rblunpack(fal_part_name, fal_part_name_dest, flags, FUPDATE_MODE_SRC_FAL | FUPDATE_MODE_DEST_FAL);
}

#if (FBOOT_USING_FILESYSTEM == 1)	

int fupdate_fal2fs(const char* fal_part_name, const char* fs_file_path_dest, uint32_t flags )
{
	return fupdate_rblunpack(fal_part_name, fs_file_path_dest, flags, FUPDATE_MODE_SRC_FAL | FUPDATE_MODE_DEST_FS);
}


int fupdate_fsprobe(const char* fal_part_name)
{
	return fupdate_rblprobe(fal_part_name, FUPDATE_MODE_SRC_FS);
}

int fupdate_fscheck(const char* fal_part_name)
{
	return fupdate_rblcheck(fal_part_name, FUPDATE_MODE_SRC_FS);
}

int fupdate_fs2fs(const char* fs_file_path, const char* fs_file_path_dest, uint32_t flags )
{
	return fupdate_rblunpack(fs_file_path, fs_file_path_dest, flags, FUPDATE_MODE_SRC_FS | FUPDATE_MODE_DEST_FS);
}

int fupdate_fs2fal(const char* fs_file_path, const char* fal_part_name_dest, uint32_t flags )
{
	return fupdate_rblunpack(fs_file_path, fal_part_name_dest, flags, FUPDATE_MODE_SRC_FS | FUPDATE_MODE_DEST_FAL);
}

#endif


#if defined(RT_USING_FINSH) && defined(FINSH_USING_MSH)
#include <finsh.h>

const char *help_info[] =
{
	"fupdate falprobe <fal part name>\n\r",
	"fupdate falcheck <fal part name>\n\r",
	"fupdate fal2fal  <fal part name> <fal part name dest>\n\r",

#if (FBOOT_USING_FILESYSTEM == 1)	
	"fupdate fal2fs   <fal part name> <fs file path dest>\n\r",
	
	"fupdate fsprobe  <fs file path>\n\r",
	"fupdate fscheck  <fs file path>\n\r",
	"fupdate fs2fal   <fs file path> <fal part name dest>\n\r",
	"fupdate fs2fs    <fs file path> <fs file path dest>\n\r",
#endif
};

void fupdate_cmd(rt_uint8_t argc, char **argv)
{
	if (argc > 2)
	{
		const char *cmd = argv[1];
		if (!rt_strcmp(cmd, "falprobe"))
		{
			fupdate_falprobe(argv[2]);
			return;
		}
		else
		if (!rt_strcmp(cmd, "falcheck"))
		{
			fupdate_falcheck(argv[2]);
			return;
		}else
		if (!rt_strcmp(cmd, "fal2fal"))
		{
			fupdate_fal2fal(argv[2], argv[3], 0);
			return;
		}
#if (FBOOT_USING_FILESYSTEM == 1)	
		else
		if (!rt_strcmp(cmd, "fal2fs"))
		{
			fupdate_fal2fs(argv[2], argv[3], 0);
			return;
		}else
		if (!rt_strcmp(cmd, "fsprobe"))
		{
			fupdate_fsprobe(argv[2]);
			return;
		}else
		if (!rt_strcmp(cmd, "fscheck"))
		{
			fupdate_fscheck(argv[2]);
			return;
		}else
		if (!rt_strcmp(cmd, "fs2fal"))
		{
			fupdate_fs2fal(argv[2], argv[3], 0);
			return;
		}else
		if (!rt_strcmp(cmd, "fs2fs"))
		{
			fupdate_fs2fs(argv[2], argv[3], 0);
			return;
		}
#endif
	}
	{
		rt_kprintf("usage:\n");
		for (int i = 0; i < sizeof(help_info) / sizeof(char *); i++)
		{
			rt_kputs(help_info[i]);
		}
		rt_kprintf("\n");
	}
}
MSH_CMD_EXPORT_ALIAS(fupdate_cmd, fupdate, fupdate command);

#endif

#endif /* FBOOT_USING_FUPDATE */
